using System;
using System.Collections;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Sedna.Core.Controller;
using Sedna.Core.Globalization;
using Sedna.Core.Support;
using Spring.Util;

namespace Sedna.Core.Controls.Support
{
	public sealed class ControlUtil
	{
		private ControlUtil()
		{
		}
	    
        #region Execute methods

        public static object ExecuteOnLoad(IDictionary executionContext, HttpContext context, IConfiguration configuration, string currentScopePrefix)
		{
            return ExecuteAction((IExecutionContext)executionContext, context, configuration, currentScopePrefix, "onLoad");
		}


        public static object ExecuteOnPreRender(IDictionary executionContext, HttpContext context, IConfiguration configuration, string currentScopePrefix)
		{
            return ExecuteAction((IExecutionContext)executionContext, context, configuration, currentScopePrefix, "onPreRender");
		}

        public static object ExecuteOnPreRenderComplete(IDictionary executionContext, HttpContext context, IConfiguration configuration, string currentScopePrefix)
        {
            return ExecuteAction((IExecutionContext)executionContext, context, configuration, currentScopePrefix, "onPreRenderComplete");
        }

        public static object ExecuteOnDataLoad(IDictionary executionContext, HttpContext context, IConfiguration configuration, string currentScopePrefix)
        {
            return ExecuteAction((IExecutionContext)executionContext, context, configuration, currentScopePrefix, "onDataLoad");
        }

        public static object ExecuteOnAfterDataLoad(IDictionary executionContext, HttpContext context, IConfiguration configuration, string currentScopePrefix)
        {
            return ExecuteAction((IExecutionContext)executionContext, context, configuration, currentScopePrefix, "onAfterDataLoad");
        }

	    public static object ExecuteAction(IExecutionContext executionContext, HttpContext context, IConfiguration configuration, string currentScopePrefix, string actionName)
		{
			IActionExecutor actionExecutor = (IActionExecutor)SpringContextFactory.GetContext().GetObject("runtime.ActionExecutor");
            return actionExecutor.ExecuteAction(executionContext, configuration, currentScopePrefix, actionName);			
		}

	    public static void ExecuteAction(IExecutionContext executionContext, HttpContext context, IConfiguration configuration, string currentScopePrefix)
		{
			IActionExecutor actionExecutor = (IActionExecutor)SpringContextFactory.GetContext().GetObject("runtime.ActionExecutor");
            actionExecutor.ExecuteAction(executionContext, configuration, currentScopePrefix);
        }

        public static object ExecuteOnValidate(IDictionary executionContext, HttpContext context, IConfiguration configuration, string currentScopePrefix)
        {
            return ExecuteAction((IExecutionContext)executionContext, context, configuration, currentScopePrefix, "onValidate");
        }

	    public static object ExecuteOnUnload(IDictionary executionContext, HttpContext context, IConfiguration configuration, string currentScopePrefix)
        {
            return ExecuteAction((IExecutionContext)executionContext, context, configuration, currentScopePrefix, "onUnload");
        }
        #endregion

        #region General utils

        //TODO: refactor to new client variable concept
        public static string GetClientVariable(Control control, string clientVariable)
        {
            if (clientVariable != null)
            {
                return clientVariable;
            }
            return GetDefaultClientVariable(control);
        }

        //TODO: refactor to new client variable concept
        public static string GetDefaultClientVariable(Control control)
        {
            return Regex.Replace(control.ClientID, "\\W+", "_") + "_var";
        }


        public static void SetupClientAttributes(WebControl control, IConfiguration configuration)
        {
            if (configuration.ClientAttributes == null || configuration.ClientAttributes.Count == 0)
            {
                return;
            }

            for (IDictionaryEnumerator de = configuration.ClientAttributes.GetEnumerator(); de.MoveNext(); )
            {
                control.Attributes.Add((string)de.Key, (string)de.Value);
            }

        }

        public static IMessageManager ExtractMessageManager(WebControl control)
        {
            IConfigurationAware configurationAware = control as IConfigurationAware;
            if (configurationAware != null && configurationAware.Configuration != null && configurationAware.Configuration.MessageManager != null)
            {
                return configurationAware.Configuration.MessageManager;
            }

            IMessageManagerAware messageManagerAware = control as IMessageManagerAware;
            if (messageManagerAware != null && messageManagerAware.MessageManager != null)
            {
                return messageManagerAware.MessageManager;
            }

            return (IMessageManager)SpringContextFactory.GetContext().GetObject("runtime.MessageManager");
        }
	    
        public static void EnsureIdAttribute(WebControl control)
		{
			if (control.ID==null)
			{
				control.Attributes.Add("id", control.ClientID);
			}
		}

		public static void EnsureIdAttribute(HtmlControl control)
		{
			if (control.ID==null)
			{
				control.Attributes.Add("id", control.ClientID);
			}
		}

		public static IDictionary ResolveClientScriptingControls(IDictionary controls, Control namingContainer)
		{
			if (controls==null||controls.Count==0)
			{
				return null;
			}
			IDictionary resolvedControls=new Hashtable(controls.Count);
			foreach (DictionaryEntry entry in controls)
			{
				IClientScriptingControl clientScriptingControl=namingContainer.FindControl((string)entry.Value) as IClientScriptingControl;		
				if (clientScriptingControl!=null)
				{
					resolvedControls.Add(entry.Key, clientScriptingControl.ClientVariable);
					continue;
				}
				resolvedControls.Add(entry.Key, entry.Value);

			}
			return resolvedControls;
        }


        public static void RenderScriptAttributes(HtmlTextWriter writer, IDictionary attributes)
        {
            foreach (DictionaryEntry entry in attributes)
            {
                writer.AddAttribute("sedna:" + (string)entry.Key, (string)entry.Value);
            }
        }
        #endregion


    }
}
